package com.cloud.lucene.service;

import com.cloud.lucene.domain.BookContent;
import com.cloud.lucene.domain.PageQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
public class LuceneService {

    @Autowired
    private IndexWriter indexWriter;

    @Autowired
    private Analyzer analyzer;

    @Autowired
    private SearcherManager searcherManager;

    public void createIndex(List<BookContent> bookContentList) throws IOException {
        List<Document> docs = new ArrayList<Document>();
        for (BookContent p : bookContentList) {
            Document doc = new Document();
            doc.add(new StringField("id", p.getId() + "", Field.Store.YES));
            doc.add(new TextField("name", p.getName(), Field.Store.YES));
            doc.add(new StringField("category", p.getCategory(), Field.Store.YES));
            Double price = p.getPrice();
            // 建立倒排索引
            doc.add(new DoublePoint("price", price));
            // 正排索引用于排序、聚合
            doc.add(new DoubleDocValuesField("price", price));
            // 存储到索引库
            doc.add(new StoredField("price", price));
            doc.add(new TextField("tip", p.getTip(), Field.Store.YES));
            docs.add(doc);
        }
        indexWriter.addDocuments(docs);
        indexWriter.commit();
    }


    public PageQuery<BookContent> search(PageQuery<BookContent> pageQuery) throws IOException, ParseException {
        searcherManager.maybeRefresh();
        IndexSearcher indexSearcher = searcherManager.acquire();
        BookContent params = pageQuery.getParams();
        Map<String, String> queryParam = pageQuery.getQueryParam();
        BooleanQuery.Builder builder = new BooleanQuery.Builder();

        // 排序规则
        Sort sort = new Sort();
        sort.setSort(new SortField("price", SortField.Type.DOUBLE, true));


        // 模糊匹配,匹配词
//        String keyStr = queryParam.get("searchKeyStr");
//        if (keyStr != null) {
//            // 输入空格,不进行模糊查询
//            if (!"".equals(keyStr.replaceAll(" ", ""))) {
//                builder.add(new QueryParser("name", analyzer).parse(keyStr), BooleanClause.Occur.MUST);
//            }
//        }

        if(null!=params.getTip()){
            builder.add(new QueryParser("tip", analyzer).parse(params.getTip()), BooleanClause.Occur.MUST);
        }

        // 精确查询
        if (params.getCategory() != null) {
            builder.add(new TermQuery(new Term("category", params.getCategory())), BooleanClause.Occur.MUST);
        }

        //范围匹配
//        if (queryParam.get("lowerPrice") != null && queryParam.get("upperPrice") != null) {
//            builder.add(FloatPoint.newRangeQuery("price", Float.parseFloat(queryParam.get("lowerPrice")),
//                    Float.parseFloat(queryParam.get("upperPrice"))), BooleanClause.Occur.MUST);
//        }

        TopDocs topDocs = indexSearcher.search(builder.build(), pageQuery.getPageNum() * pageQuery.getPageSize(), sort);
        log.info("总数:{}", topDocs.totalHits);
        ScoreDoc[] hits = topDocs.scoreDocs;
        for (int i = 0; i < hits.length; i++) {
            Document doc = indexSearcher.doc(hits[i].doc);
            log.info("doc:{}", doc);
        }
        return pageQuery;
    }

    public void deleteIndexById(String id) throws IOException {
        indexWriter.deleteDocuments(new Term("id",id));
        indexWriter.commit();
    }
}
